package concurrency

import (
	"fmt"
	"sync"
	"time"
)

/**
sync.Cond 是 Go 语言中用于实现同步机制的类型。它主要用于通知某个协程需要等待其他协程完成某些任务。
使用 sync.Cond 的方法：
创建一个 sync.Cond 实例。
在需要等待的协程中调用 Wait 方法。这会导致协程暂停直到收到通知。
在另一个协程中调用 Signal 或 Broadcast 方法。Signal 方法可以通知一个协程，而 Broadcast 方法可以通知所有等待的协程。
通过使用 sync.Cond，可以实现精细的线程同步控制，从而有效地提高应用程序的性能。
*/

var myLock sync.Cond

func producer(ch chan string, name string) {
	for {
		myLock.L.Lock()
		for len(ch) == cap(ch) {
			myLock.Wait()
		}
		ch <- name
		myLock.L.Unlock()
		myLock.Signal()
		time.Sleep(time.Second)
	}
}

func consumer(ch chan string) {
	for {
		myLock.L.Lock()
		for len(ch) <= 0 {
			myLock.Wait()
		}
		fmt.Println("消费了:", <-ch)
		myLock.L.Unlock()
		myLock.Signal()
	}
}

func main() {
	//创建管道用于退出程序
	var exit = make(chan bool)
	myLock.L = new(sync.Mutex)

	ch := make(chan string, 1)
	go producer(ch, "一号产品")
	go producer(ch, "二号产品")
	go consumer(ch)

	<-exit
}
